
// g++ test.cpp -o orb_extraction_cuda `pkg-config --cflags --libs opencv4`
#include <iostream>
#include <chrono>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/cudafeatures2d.hpp>

int main() {
    // 读取图像
    cv::Mat img = cv::imread("/home/john/LJJ_SRC/opencv_test/surf_keypoint_gpu/pic/9_Infrared.png", cv::IMREAD_GRAYSCALE);
    cv::Mat img1 = cv::imread("/home/john/LJJ_SRC/opencv_test/surf_keypoint_gpu/pic/10_Infrared.png", cv::IMREAD_GRAYSCALE);
    if (img.empty()) {
        std::cerr << "Error: Could not open input image." << std::endl;
        return 1;
    }

    // 开始计时
    auto start = std::chrono::high_resolution_clock::now();
    // 将图像上传到 GPU
    cv::cuda::GpuMat img_gpu(img1);

    // 创建 ORB 对象
    cv::Ptr<cv::cuda::ORB> orb = cv::cuda::ORB::create();



    // 提取关键点和描述符
    cv::cuda::GpuMat keypoints_gpu, descriptors_gpu;
    orb->detectAndComputeAsync(img_gpu, cv::cuda::GpuMat(), keypoints_gpu, descriptors_gpu);

    // 将结果从 GPU 下载到 CPU
    std::vector<cv::KeyPoint> keypoints;
    orb->convert(keypoints_gpu, keypoints);
    cv::Mat descriptors;
    descriptors_gpu.download(descriptors);


    // 结束计时并打印程序运行时间
    auto end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double, std::milli> elapsed = end - start;
    std::cout << "Elapsed time: " << elapsed.count() << " ms" << std::endl;

    // 显示关键点
    cv::Mat img_keypoints;
    cv::drawKeypoints(img1, keypoints, img_keypoints, cv::Scalar::all(-1), cv::DrawMatchesFlags::DEFAULT);
    cv::imshow("ORB Keypoints", img_keypoints);
    cv::waitKey(0);



    while(1){
    // 开始计时
    auto start = std::chrono::high_resolution_clock::now();
    // 将图像上传到 GPU
    cv::cuda::GpuMat img_gpu(img);

    // 创建 ORB 对象
    cv::Ptr<cv::cuda::ORB> orb = cv::cuda::ORB::create();



    // 提取关键点和描述符
    cv::cuda::GpuMat keypoints_gpu, descriptors_gpu;
    orb->detectAndComputeAsync(img_gpu, cv::cuda::GpuMat(), keypoints_gpu, descriptors_gpu);

    // 将结果从 GPU 下载到 CPU
    std::vector<cv::KeyPoint> keypoints;
    orb->convert(keypoints_gpu, keypoints);
    cv::Mat descriptors;
    descriptors_gpu.download(descriptors);


    // 结束计时并打印程序运行时间
    auto end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double, std::milli> elapsed = end - start;
    std::cout << "Elapsed time: " << elapsed.count() << " ms" << std::endl;

    // 显示关键点
    cv::Mat img_keypoints;
    cv::drawKeypoints(img, keypoints, img_keypoints, cv::Scalar::all(-1), cv::DrawMatchesFlags::DEFAULT);
    cv::imshow("ORB Keypoints", img_keypoints);
    cv::waitKey(0);}

    return 0;
}

